﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyLib {
	/// <summary>
	/// 
	/// </summary>
	public static class StringExtensions {
		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <param name="maxLength"></param>
		/// <param name="tailLength"></param>
		/// <param name="keepExt"></param>
		/// <returns></returns>
		public static string AbbreviatedTo(this string s, int maxLength = 32, int tailLength = 3, bool keepExt = true) {
			System.Diagnostics.Debug.Assert(maxLength > 0);
			System.Diagnostics.Debug.Assert(tailLength >= 0);

			if (s == null)
				return string.Empty;

			if (s.Length <= maxLength)
				return s;

			const string ELLIPSE = "...";

			string ext = null;
			var mainLength = maxLength - ELLIPSE.Length - tailLength;
			var buf = new StringBuilder(maxLength);
			var tail = string.Empty;
			var tailEnd = s.Length;
			if (keepExt) {
				var posExt = s.LastIndexOf('.');
				if (posExt != -1) {
					ext = s.Substring(posExt);

					mainLength -= ext.Length;
					tailEnd = posExt;
				}
			}

			if (mainLength < 1)
				mainLength = 1;

			buf.Append(s.Substring(0, mainLength));
			buf.Append(ELLIPSE);
			var tailPos = tailEnd - tailLength;
			if (tailPos > mainLength) {
				buf.Append(s.Substring(tailPos, tailLength));
			}

			if (keepExt && !string.IsNullOrEmpty(ext)) {
				buf.Append(ext);
			}

			return buf.ToString();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="s"></param>
		/// <returns></returns>
		public static string EncodeJsString(this string s) {
			if (s == null)
				return string.Empty;

			StringBuilder sb = new StringBuilder();
			foreach (char c in s) {
				switch (c) {
					case '\'':
						sb.Append("\\\'");
						break;
					case '\"':
						sb.Append("\\\"");
						break;
					case '\\':
						sb.Append("\\\\");
						break;
					case '\b':
						sb.Append("\\b");
						break;
					case '\f':
						sb.Append("\\f");
						break;
					case '\n':
						sb.Append("\\n");
						break;
					case '\r':
						sb.Append("\\r");
						break;
					case '\t':
						sb.Append("\\t");
						break;
					default:
						int i = (int)c;
						if (i < 32 || i > 127) {
							sb.AppendFormat("\\u{0:X04}", i);
						} else {
							sb.Append(c);
						}
						break;
				}
			}

			return sb.ToString();
		}
	} // end of StringExtensions.
}
